from cPickle import dump
from cPickle import load
import nltk
import os

# Brown:Conll2000
conversion_dictionary = {
                        'BEZ':'VBZ',
                        'AT':'DT',
                        'NP':'NNP',
                        'BER':'VBP',
                        'PPSS':'PRP',
                        'PPS':'PRP',
                        'AP':'JJ',
                        'PP$':'PRP$',
                        'NR':'NN',
                        'HV':'VBP',
                        'BEN':'VBN',
                        'BEDZ':'VBD',
                        '*':'RB',
                        'WPS':'WP',
                        'HVZ':'VBZ', # has
                        'NN-TL':'NN', # noun-title
                        'IN-TL':'IN', # in-title
                        'AT-TL':'DT', # article-title
                        'NNS-TL':'NNS', # Noun Plural-title
                        'CC-TL':'CC',
                        'QL':'RBS', # most (qualifiers)
                        #'NP$':'NN$', # Possesive Proper Noun
                        'JJT':'JJS', # newest, fiercest, bravest, safest
                        'HVG':'VBG', # having
                        'HVD':'VBD', # verb "to have", past tense : had
                        'FW-NN-TL':'NN', # foreign-noun title "Tour"
                        'JJ-TL':'JJ', # jj-title "foreign"
                        'VBN-TL':'VBN', # vbn - title
                        'PPO':'PRP', # pronoun, personal, accusative 'them it him me us you 'em her thee we'uns' 'she gave her'
                        'OD':'JJ', # numeral, ordinal
                        'OD-TL':'JJ', # numeral, ordinal
                        'CS':'IN',
                        'NP-TL':'NNP', # NP-title
                        'NR-TL':'RB', # noun, singular, adverbial  title 'Friday home southeast'
                        'BE':'VB', # verb "to be", infinitive or imperative 
                        'BEG':'VBG', # being
                        'BED':'VBD', # were
                        'PPL':'PRP', # pronoun, singular, reflexive
                        'DOD':'VBD', # did
                        'PN':'NN', # pronoun, nominal
                        'DO':'VB', # verb "to do", uninflected present tense, infinitive or imperative 
                        }
word_conversion_dictonary = {
                             'as':'IN',
                             }

word_tag_conversion_dictonary = {
                                 ('that','CS'):'DT',
                                 ('All','ABN'):'PDT',
                                 ('all','ABN'):'PDT',
                                 ('than','CS'):'IN',
                                 ('any','DTI'):'RB',
                                 ('until','CS'):'IN'
                                 }
def convertBrownTagToConnll2000Tag(brown_tuple,keepOriginal=False):
    """ convert a brown tag to a connll2000 tag
    input: (word, tag) """
    #(word, tag) = brown_tuple
    #word = brown_tuple[0].lower()
    word = brown_tuple[0]
    tag = brown_tuple[1]
    tuple_lower = (word, tag)
    # first try word specific conversions...
    
    connll_tag = word_tag_conversion_dictonary.get(tuple_lower)
    if connll_tag == None:
        connll_tag = word_conversion_dictonary.get(word)
    if connll_tag == None:
        connll_tag = conversion_dictionary.get(tag)
    if connll_tag == None:
        connll_tag = tag

    # check if word needs to be split in more parts...
    if tag == "NP$":
        # noun+'s e.g.: friend's 
        left, sep, right = word.partition("'")
        leftpart = (left, "NN", tag)
        rightpart = (sep+right, "POS", tag)
        return [leftpart, rightpart]
    if tag == "NN$":
        # noun+'s e.g.: friend's 
        left, sep, right = word.partition("'")
        leftpart = (left, "NN", tag)
        rightpart = (sep+right, "POS", tag)
        return [leftpart, rightpart]
    if tag == "DOD*":
        # didn't
        leftpart = ("did", "VBD", tag)
        rightpart = ("not", "RB", tag)
        return [leftpart, rightpart]
    if tag == "WPS+BEZ":
        # Who's: WH-pronoun, nominative + verb "to be", present, 3rd person singular 
        left, sep, right = word.partition("'")
        leftpart = (left, "WP", tag)
        rightpart = ("is", "VBZ", tag)
        return [leftpart, rightpart]
    if tag == "WDT+BEZ":
        # Who's: WH-pronoun, nominative + verb "to be", present, 3rd person singular 
        left, sep, right = word.partition("'")
        leftpart = (left, "WP", tag)
        rightpart = ("is", "VBZ", tag)
        return [leftpart, rightpart]
    if tag == "VB+PPO":
        # verb, uninflected present tense + pronoun, personal, accusative
        # let's lemme gimme
        leftpart = ("let", "VB", tag)
        rightpart = ("is", "PRP", tag)
        return [leftpart, rightpart]
    return [(word, connll_tag, tag)]


def convertBrownTagListToConnll2000(tagged_words,keepOriginal=True):
    """ [(word, b_tag), (word, b_tag), ...] """
    new_tagged_words = []
    for tagged_word in tagged_words:
        tuple_array = convertBrownTagToConnll2000Tag(tagged_word,keepOriginal)
        if len(tuple_array) == 1:
            new_tagged_words.append(tuple_array[0])
        else:
            new_tagged_words.append(tuple_array[0])
            new_tagged_words.append(tuple_array[1])
     
    if keepOriginal==False:
        # drop the original Brown tag
        new_tagged_words = [(word, c_tag) for (word, c_tag, b_tag) in new_tagged_words] 
    return new_tagged_words
        

class TagStore:
    def __init__(self):
        self.f = None
        self.curdir = os.path.dirname(os.path.abspath(__file__))
        
    def createFile(self, filename):
        """Creates a file in the current dir, only suplly the filename, not the complete path!"""
        __dir__ = os.path.dirname(os.path.abspath(__file__))
        # filename = "fetch" + str(index) + ".txt"
        filepath = os.path.join(__dir__, filename)
        print filepath
        #f = codecs.open('test', encoding='utf-8', mode='w')
        self.f = open(filepath, 'w')
        return self.f
    
    def saveTagger(self, tagger, taggername):
        output = open(str(taggername)+'.pkl', 'wb')
        dump(tagger, output, -1)
        output.close()
        
    def loadTagger(self, taggername):
        #print self.curdir + "\\" + taggername
        #print taggername
        location = self.curdir + "\\" + taggername
        input = open(str(location)+'.pkl', 'rb')
        tagger = load(input)
        input.close()
        return tagger

        
class TaggerTrainer:
    def __init__(self):
        pass

# Sec   Genre           Sec   Genre                 Sec   Genre
# a     Press: Reportage  b     Press: Editorial    c     Press: Reviews
# d     Religion          e     Skill and Hobbies   f     Popular Lore
# g     Belles-Lettres    h     Government          j     Learned
# k     Fiction: General  k     Fiction: General    l     Fiction: Mystery
# m     Fiction: Science  n     Fiction: Adventure  p     Fiction: Romance
# r     Humor            

# Brown corpus tag set: http://www.scs.leeds.ac.uk/amalgam/tagsets/brown.html                
    def getBrown(self):
        self.brownCategories = ['a','b']
        brown_corpus = nltk.corpus.brown.tagged_sents(categories=self.brownCategories)  
        t0 = nltk.DefaultTagger('NN')
        t1 = nltk.UnigramTagger(brown_corpus, backoff=t0)
        t2 = nltk.BigramTagger(brown_corpus, backoff=t1)
        tagger = t2;
        print nltk.tag.accuracy(tagger, brown_corpus)
        return tagger

    def getBrown2(self):
        self.brownCategories = ['a','b','c','d','e','f','h','j','k','l','m','n','p','r' ]
        brown_corpus = nltk.corpus.brown.tagged_sents(categories=self.brownCategories)  
        t0 = nltk.DefaultTagger('NN')
        t1 = nltk.UnigramTagger(brown_corpus, backoff=t0)
        t2 = nltk.BigramTagger(brown_corpus, backoff=t1)
        tagger = t2;
        print nltk.tag.accuracy(tagger, brown_corpus)
        return tagger